package cn.js189.uqc.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Random;

/**
 * @author lj
 * @date 2023-07-14 10:38
 * 用于生成GUID
 */
public class GuidGenerator{
    
    private GuidGenerator(){/*empty*/}

    private static final Logger logger = LoggerFactory.getLogger(GuidGenerator.class);
    private static Random myRand;
    /**
     * 安全随机对象
     */
    private static SecureRandom mySecureRand;

    /**
     * ip地址字符串
     */
    private static String sId;

    static
    {
        mySecureRand = new SecureRandom();
        //用安全随机对象产生一随机数并用该随机数初始化基本java随机对象
        long secureInitializer = mySecureRand.nextLong();
        myRand = new Random(secureInitializer);

        try
        {
            //获得当前主机的ip地址字符串
            sId = InetAddress.getLocalHost().toString();
        }
        catch (UnknownHostException e)
        {
            e.printStackTrace();
        }
    }



    /**
     * 缺省的产生随机GUID的方法
     * @return 正确返回32字节的字符串，错误则返回长度为零的字符串
     */
    public static String genRandomGUID()
    {
        return genRandomGUID(false);
    }

    /**
     * 产生随机GUID的方法,考虑产生GUID的效率，将来可以应用设计模式，先生成一堆id并缓存
     * @param secure true  : 带安全选项，用安全随机数对象生成
     *               false : 不带安全选项，用基本随机数对象生成
     * @return 正确返回32字节的字符串，错误则返回长度为零的字符串
     */
    public static String genRandomGUID(boolean secure)
    {
        //消息消化对象消化前的字符串
        String valueBeforeMD5 = "";
        //经消息消化对象消化后的GUID字符串
        StringBuilder valueAfterMD5 = new StringBuilder();
        //消息消化对象
        MessageDigest md5 = null;
        StringBuilder sbValueBeforeMD5 = new StringBuilder();

        try
        {
            md5 = MessageDigest.getInstance("MD5");
        }
        catch (NoSuchAlgorithmException e)
        {
            logger.info("Error:{} ",e.getMessage());
            return valueBeforeMD5;
        }

        //获得系统时间
        long time = System.currentTimeMillis();
        //随机数
        long rand = 0;
        //用安全随机对象获得随机数
        if (secure)
        {
            rand = mySecureRand.nextLong();
        }
        else
        //用基本随机对象获得随机数
        {
            rand = myRand.nextLong();
        }

        //拼接组成GUID的各个信息
        sbValueBeforeMD5.append(sId);
        sbValueBeforeMD5.append(":");
        sbValueBeforeMD5.append(time);
        sbValueBeforeMD5.append(":");
        sbValueBeforeMD5.append(rand);
        valueBeforeMD5 = sbValueBeforeMD5.toString();
        md5.update(valueBeforeMD5.getBytes());
        //消息消化对象进行消化动作，返回128bit
        byte[] array = md5.digest();

        String strTemp = "";
	    for (byte b : array) {
		    strTemp = (Integer.toHexString(b & 0XFF));
		    if (strTemp.length() == 1) {
			    valueAfterMD5.append("0").append(strTemp);
		    } else {
			    valueAfterMD5.append(strTemp);
		    }
	    }
        //GUID标准格式如：C2FEEEAC-CFCD-11D1-8B05-00600806D9B6
        return valueAfterMD5.toString().toUpperCase();
    }

}
